package com.guangyuan.network.datasource.pool.util;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.log4j.Logger;

import com.guangyuan.network.constants.SqlType;

public class ConnectionUtil {
	private static DataSource dataSource;
	private static Logger logger = Logger.getLogger(ConnectionUtil.class);
	public static GenericObjectPool connectionPool;
	static {
		try {
			setupDataSource();
		} catch (FileNotFoundException e) {
			logger.error(e.getMessage());
		} catch (IOException e) {
			logger.error(e.getMessage());
		}
	}

	private static void setupDataSource() throws FileNotFoundException,
			IOException {
		Properties prop = new Properties();
		prop.load(ConnectionUtil.class.getResourceAsStream("db.properties"));
		connectionPool = new GenericObjectPool(null);
		connectionPool.setMaxActive(2);
		connectionPool.setMaxIdle(2);

		ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
				prop.getProperty("url"), prop.getProperty("username"), prop
						.getProperty("password"));

		PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(
				connectionFactory, connectionPool, null, null, false, true);

		dataSource = new PoolingDataSource(connectionPool);
	}

	public static Connection getConnection() {
		Connection conn = null;
		try {
			conn = dataSource.getConnection();
		} catch (SQLException e) {
			logger.error(e.getMessage());
		}
		return conn;
	}
	
	public static PreparedStatement getStatement(Connection conn, String sql, SqlType type) throws SQLException {
		PreparedStatement pstmt = null;
		if(SqlType.OTHER.equals(type)) {
			pstmt = conn.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY,
					ResultSet.CONCUR_READ_ONLY,
					ResultSet.HOLD_CURSORS_OVER_COMMIT);
		} else {
			pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
		}
		return pstmt;
	}
	
	public static void closeConnection(Connection conn) {
		if(null != conn) {
			try {
				conn.close();
			} catch (SQLException e) {
				logger.error(e.getMessage());
			}
		}
	}
	
	public static void closeStatement(Statement stmt) {
		if(null != stmt) {
			try {
				stmt.close();
			} catch (SQLException e) {
				logger.error(e.getMessage());
			}
		}
	}
	
	public static void closeResultSet(ResultSet rs) {
		if(null != rs) {
			try {
				rs.close();
			} catch (SQLException e) {
				logger.error(e.getMessage());
			}
		}
	}
	/**
	 * @param args
	 * @throws SQLException
	 */
	public static void main(String[] args) throws SQLException {
		System.out.println(connectionPool.getNumActive());
		System.out.println(connectionPool.getNumIdle());
		for(int i = 0; i < 2; i ++) {
			Connection conn = ConnectionUtil.getConnection();
			System.out.println(connectionPool.getNumActive());
			System.out.println(connectionPool.getNumIdle());
			conn.close();
			System.out.println(connectionPool.getNumActive());
			System.out.println(connectionPool.getNumIdle());
		}
		
		
		System.out.println(connectionPool.getNumActive());
		System.out.println(connectionPool.getNumIdle());
	}
}
